
package ch.unifr.dokpe.shortkeys;

/**
 * The abstract class parent to the shortkeys. Events and eventListener are coded here. 
 */

public abstract class AkbHook {
	protected javax.swing.event.EventListenerList listenerList = new javax.swing.event.EventListenerList();
	
	/**
	 * Add a listener to the list. 
	 * KbListener that implements KeyboardEventListener is the registered listener on start up
	 * @param listener KeyboardEventListener
	 */
	public void addEventListener(KeyboardEventListener listener){ 
		listenerList.add( KeyboardEventListener.class, listener );
	}
	
 	/**
	 * Remove a listener from the list
	 * @param listener KeyboardEventListener
	 */
	public void removeEventListener(KeyboardEventListener listener) {
		listenerList.remove( KeyboardEventListener.class, listener );
	}
	
	/**
	 * Goes accross all the registered listener starting from the end.
	 * Does not take into account 1 on 2 of the entries since, one of the entry 
	 * is just the type descriptor for the actual Eventlistener.
	 * Calls GlobalKeyPressed or GlobalKeyReleased.
	 * @param e KeyboardEvent, the event that gives the key that has been used. 
	 */
	
	private void fireKeyboardEvent(KeyboardEvent e){
		Object[] listeners = listenerList.getListenerList();
		//System.out.println("firekh event");
    // Process the listeners last to first, notifying
     // those that are interested in this event
	//as one can see the for loop skips every second entry. Because this
	//entry is just the type descriptor for the actual Eventlistener.
		for ( int i =listeners.length-2; i>=0 ; i -= 2 ) {
			if ( listeners[ i ] == KeyboardEventListener.class ){
				//System.out.println("TransState " + (e.getTransitionState()?"true":"false"));
				if (!e.getTransitionState()){
					//System.out.println(listeners[i+1].getClass().toString());
					( (KeyboardEventListener)listeners[i + 1] ).GlobalKeyPressed( e );
				} else {
				  	( (KeyboardEventListener)listeners[i + 1] ).GlobalKeyReleased( e );		
				}

			}
		}
}
	
	/**
	 * Register the dll or the hook class using JNA as a keyboard listener.
	 */

	public abstract void registerHook();

	/**
	 * Unregister the dll or the hook class using JNA as a keyboard listener. 
	 */
	public abstract void unRegisterHook();

	/**
	 * Put the data in the clipboard using ctrl+v
	 * @param delkey int how many characters we delete before using calling the shortkeys
	 */
	public abstract void pastFromClpb(int delkey);

	/**
	 * Call from KbListener to send data or commands to the keyboard hook.
	 * if vkcode = 0 we are dealing with data, else vkcode is virtual key code (listed in winuser.h) 
	 * and the correspondint command (tab, enter ...) is sent
	 * @param delkey int numbers of time we send a delete to clear the characters that have been used to call the shortkey
	 * @param data String data
	 * @param vkcode byte virtual key code
	 */
	public abstract void sendToKeyboard(int delkey, String data, byte vkcode);

	/**
	 * Called after a command or a string have been sent to release control keys
	 */
	public abstract void releaseExtendedKeys();

	/**
	 * Send a new KeyboardEvent from the keyboard hook by LowLevelKeyboardProc when a key is stroked. 
	 * This event will be reacted upon by the listeners in KbListener
	 */
		
	 public void processKey( boolean transitionState, int virtualKeyCode, boolean altPressed, boolean isExtended ) {
		//System.out.println("Java: KbHook.processKey - key = " + virtualKeyCode + (transitionState ? " released" : " pressed"));
		KeyboardEvent event = new KeyboardEvent( this, transitionState, virtualKeyCode, altPressed, isExtended);
		fireKeyboardEvent(event);
	
	}//processkey

}//class

//@MITLI@
